#include "bitstream.h"
#include <stdlib.h>
#include <stdio.h>

//convert array of char to bitstream
unsigned char *to_bitstream_compact(
			    unsigned char *src,
			    unsigned int n,
			    unsigned int *n_words
			    )
{
  //unsigned int lm_size = height * width;
  *n_words = (n + 7) / 8; //i.e.: ceil(n/8)
  unsigned char *bs = (unsigned char *)malloc((*n_words) * sizeof(unsigned char));
  unsigned int i, bs_i;
  unsigned char active = 128; //left-shifting mask (128 -> 7x, 64 -> 6x, ... , 2 -> 1x)
  unsigned char word = 0; //implicit 0-padding
  bs_i = 0;
  for(i=0; i<n; ++i) {
    word += active * src[i];
    active /= 2;
    if(active == 0) {
      bs[bs_i++] = word;
      active = 128;
      word = 0;
    }
  }
  if(bs_i < *n_words - 1)
    //incomplete word (0-padded)
    bs[bs_i++] = word;

  return bs;
}



unsigned char *to_bitstream_flat(
			    unsigned char *src,
			    unsigned int n,
			    unsigned int *n_words
			    )
{
  *n_words = 8 * n;
  unsigned char *bs = (unsigned char *)malloc(*n_words * sizeof(unsigned char));
  unsigned int i, j, bs_i=0;
  for(i=0; i<n; ++i)
    for(j=8; j>0; --j)
      bs[bs_i++] = (src[i] >> (j-1)) & 1;

  return bs;
}

void bistream_to_file(
		      const char *fname,
		      unsigned char *bs1,
		      unsigned char *bs2,
		      unsigned char *bs3,
		      unsigned int n1,
		      unsigned int n2,
		      unsigned int n3
		      )
{
  int i;
  FILE *fp = fopen(fname, "w");
  fprintf(fp,"#START\n");
  //fprintf(fp,"#(compressed) location map\n");
  for(i=0; i<32; ++i)
    fprintf(fp, "%d", bs1[i]);
  //fprintf(fp,"\n");
  for(; i<n1; ++i)
    fprintf(fp, "%d", bs1[i]);
  //fprintf(fp,"\n");
  //fprintf(fp, "#original LSB\n");
  for(i=0; i<n2; ++i)
    fprintf(fp, "%d", bs2[i]);
  //fprintf(fp,"\n");
  //fprintf(fp, "#payload\n");
  for(i=0; i<n3; ++i)
    fprintf(fp, "%d", bs3[i]);
  fprintf(fp, "\n#END\n");
  fclose(fp);
}

void bistream_to_file_single(
		      const char *fname,
		      unsigned char *bs1,
		      unsigned int n1
		      )
{
  int i;
  FILE *fp = fopen(fname, "w");
  fprintf(fp,"#START\n");
  for(i=0; i<n1; ++i)
    fprintf(fp, "%d", bs1[i]);
  fprintf(fp, "\n#END\n");
  fclose(fp);
}

unsigned int to_int32(
		      unsigned char *b,
		      unsigned int start_pos
		      )
{
  unsigned int res = 0;
  int i;
  for(i=31; i>=0; --i)
    res += (b[start_pos + i] << (31 - i));
  return res;
}
